{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d882c33e",
   "metadata": {},
   "source": [
    "# Accessing IBM Quantum\n",
    "\n",
    "Register for a free account at https://quantum-computing.ibm.com/ and copy your API token from the IBM Quantum Dashboard (first page on login).\n",
    "\n",
    "Set an environment variable by pasting your token, for example:\n",
    "```\n",
    "    export IBM_QUANTUM_TOKEN=\"123456789qwertyuiopzxcvbnmasdfghjkl\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0da160aa",
   "metadata": {},
   "source": [
    "We also need to install and import `covalent`, along with the other requirements below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9478356e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "covalent\n",
      "qiskit==0.40.0\n",
      "qiskit-ibm-runtime==0.8.0\n"
     ]
    }
   ],
   "source": [
    "with open(\"./requirements.txt\", \"r\") as file:\n",
    "    for line in file:\n",
    "        print(line.rstrip())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d776700e",
   "metadata": {},
   "source": [
    "# Evaluating a circuit inside an Electron"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c81b43f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "import covalent as ct\n",
    "from qiskit import QuantumCircuit\n",
    "from qiskit.compiler import transpile\n",
    "from qiskit.quantum_info import SparsePauliOp\n",
    "from qiskit_ibm_runtime import Estimator, QiskitRuntimeService, Session"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47027e0f",
   "metadata": {},
   "source": [
    "Define a simple circuit and use it inside a task."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fdaf78fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def _circuit(phi_z: float, phi_y: float):\n",
    "    \"\"\"create and return a basic qiskit circuit\"\"\"\n",
    "    qc = QuantumCircuit(2)\n",
    "    qc.rz(phi_z, 0)\n",
    "    qc.cnot(0, 1)\n",
    "    qc.ry(phi_y, 1)\n",
    "    return qc\n",
    "\n",
    "\n",
    "@ct.electron(deps_pip=ct.DepsPip([\"qiskit==0.40.0\"]))\n",
    "def evaluate_circuit(phi_z: float, phi_y: float, token: str, shots=100):\n",
    "    QiskitRuntimeService.save_account(channel=\"ibm_quantum\",\n",
    "                                      token=token,\n",
    "                                      instance=\"hub/group/project\",\n",
    "                                      overwrite=True)\n",
    "\n",
    "    with Session(service=QiskitRuntimeService(), backend=\"ibm_nairobi\"):\n",
    "        estimator = Estimator()\n",
    "        return estimator.run(circuits=_circuit(phi_z, phi_y),\n",
    "                             observables=[SparsePauliOp(\"IZ\")],\n",
    "                             shots=shots).result()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a235e509",
   "metadata": {},
   "source": [
    "Next, define a workflow that uses this task. A minimal example is shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e12608f",
   "metadata": {},
   "outputs": [],
   "source": [
    "@ct.lattice\n",
    "def test(token: str):\n",
    "    \"\"\"a very basic, single-electron workflow\"\"\"\n",
    "    return evaluate_circuit(0.1, 0.2, token)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f222da9",
   "metadata": {},
   "source": [
    "Finally, dispatch the workflow using `ct.dispatch` and pass the IBM Quantum token from our local environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "594d12db",
   "metadata": {},
   "outputs": [],
   "source": [
    "# run this cell to dispatch the workflow\n",
    "\n",
    "token = os.environ[\"IBM_QUANTUM_TOKEN\"]  # get token from local environment\n",
    "\n",
    "dispatch_id = ct.dispatch(test)(token)\n",
    "print(f\"\\n{dispatch_id}\")\n",
    "\n",
    "workflow_result = ct.get_result(dispatch_id, wait=True)\n",
    "print(workflow_result.result)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  },
  "vscode": {
   "interpreter": {
    "hash": "c3f7ec28ad043084587ef41d36e41a2d255e458cfe8579c8d13a7e90aa7f27bb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
